using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Events;
using StockholmsStad.Runtime.Serialization.DataContract;
using StockholmsStad.Windows.UI.Facade.Events;
using StockholmsStad.Windows.UI.Modules.Couple.Interfaces;
using StockholmsStad.Runtime.Serialization.DataContract.Enums;
using StockholmsStad.Windows.UI.Modules.Couple.Events;
using StockholmsStad.Windows.UI.Modules.Couple.Models;

namespace StockholmsStad.Windows.UI.Modules.Couple.Views
{
    /// <summary>
    /// Interaction logic for CouplesListView.xaml
    /// </summary>
    public partial class CouplesListView : ICouplesListView
    {
        private readonly ICoupleService coupleService;
        private readonly SubscriptionToken subscriptionToken;
        private readonly IEventAggregator eventAggregator;

        private bool isInChangeMode;

        public CouplesListView(ICoupleService service, IEventAggregator aggregator)
        {
            eventAggregator = aggregator;
            InitializeComponent();
            Model = new ObservableCollection<CouplesSummaryItem>();
            coupleService = service;

            Loaded += CouplesListView_Loaded;
            service.GetTicketsCompleted += service_GetTicketsCompleted;

            var addedCoupleEvent = eventAggregator.GetEvent<CoupleSummaryItemAddedEvent>();
            var changedCoupleEvent = eventAggregator.GetEvent<CoupleChangedEvent>();
            var addedBookingEvent = eventAggregator.GetEvent<BookingAddedEvent>();
            var canceledBookingEvent = eventAggregator.GetEvent<BookingCancelledEvent>();
            var changedCeremonyEvent = eventAggregator.GetEvent<CeremonyChangedEvent>();
            var isInChangeModeEvent = eventAggregator.GetEvent<IsInChangeModeEvent>();

            if (subscriptionToken != null)
            {
                addedCoupleEvent.Unsubscribe(subscriptionToken);
                changedCoupleEvent.Unsubscribe(subscriptionToken);
                addedBookingEvent.Unsubscribe(subscriptionToken);
                canceledBookingEvent.Unsubscribe(subscriptionToken);
                changedCeremonyEvent.Unsubscribe(subscriptionToken);
                isInChangeModeEvent.Unsubscribe(subscriptionToken);
            }

            subscriptionToken = addedCoupleEvent.Subscribe(CoupleAddedEventHandler, ThreadOption.UIThread, false);
            subscriptionToken = changedCoupleEvent.Subscribe(CoupleChangedEventHandler, ThreadOption.UIThread, false);
            subscriptionToken = addedBookingEvent.Subscribe(BookingAddedEventHandler, ThreadOption.UIThread, false);
            subscriptionToken = canceledBookingEvent.Subscribe(BookingCancelledEventHandler, ThreadOption.UIThread, false);
            subscriptionToken = changedCeremonyEvent.Subscribe(CeremonyChangedEventHandler, ThreadOption.UIThread, false);
            subscriptionToken = isInChangeModeEvent.Subscribe(IsInChangeModeEventHandler, ThreadOption.UIThread, false);
        }

        private void IsInChangeModeEventHandler(bool change)
        {
            if(isInChangeMode != change)
                isInChangeMode = change;
        }

        private void CeremonyChangedEventHandler(CeremonyPresentationModel obj)
        {
            btnSearch_Click(null, null);
        }

        private void BookingCancelledEventHandler(BookingPresentationModel item)
        {
            btnSearch_Click(null, null);
        }

        private void BookingAddedEventHandler(BookingPresentationModel item)
        {
            btnSearch_Click(null, null);
        }

        private void CoupleAddedEventHandler(CouplesSummaryItem item)
        {
            if(!Model.Contains(item))
                Model.Add(item);
            listViewUsers.SelectedIndex = Model.Count - 1;
        }

        private void CoupleChangedEventHandler(CouplesSummaryItem item)
        {
            var index = -1;
            for (var i = 0; i < Model.Count; i++)
            {
                if (Model[i].TicketId != item.TicketId) continue;
                //Uppdatera
                item.Status = Model[i].Status;
                item.BookingDate = Model[i].BookingDate;
                item.CeremonyType = Model[i].CeremonyType;
                item.Note = Model[i].Note;
                item.ImpedimentDocIssuedDate = Model[i].ImpedimentDocIssuedDate;
                Model[i] = item;
                index = i;
                break;
            }
            if (index >= 0)
            {
                listViewUsers.SelectedIndex = index;
            }
        }

        public ObservableCollection<CouplesSummaryItem> Model
        {
            get { return DataContext as ObservableCollection<CouplesSummaryItem>; }
            set { DataContext = value; }
        }

        public event EventHandler<DataEventArgs<int>> CoupleSelected = delegate { };

        private void CouplesListView_Loaded(object sender, RoutedEventArgs e)
        {
            //coupleService.RetriveTicketsASync(string.Empty, string.Empty, TicketStatusType.Started);
            Model = coupleService.RetrieveTickets(string.Empty, string.Empty, TicketStatusType.Started);
        }

        private void service_GetTicketsCompleted(object sender, CouplesSummaryItemEventArgs e)
        {
            Model = e.Data;
        }

        private void listViewPerson_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                var selected = e.AddedItems[0] as CouplesSummaryItem;
                if (selected != null)
                {
                    CoupleSelected(this, new DataEventArgs<int>(selected.TicketId));
                }
            }
        }

        private void btnSearch_Click(object sender, RoutedEventArgs e)
        {
            var ticketStatus = rbActive.IsChecked.HasValue && rbActive.IsChecked.Value
                                   ? TicketStatusType.Started
                                   : TicketStatusType.NotCarriedOut;

            Model = coupleService.RetrieveTickets(tbPartOfName.Text, tbPartOfBirth.Text, ticketStatus);
        }

    }
}